/**
 * 
 */
package com.skyme.automation.generate.common.db;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.ui.PlatformUI;

import com.skyme.automation.generate.model.settings.JDBCDriverSetting;
import com.skyme.automation.generate.preferences.PreferenceInitializer;
import com.skyme.automation.generate.preferences.jdbc.JDBCPathDialog;

/**
 * 抽象数据库基类
 * @author zhangfeng
 *
 */
public abstract class DBManagerBase implements DBManager{
	
	public static final String ID = "StandardSQL";
	
	private Set<String> reservedWords = new HashSet<String>();

	public DBManagerBase() {
		DBManagerFactory.addDB(this);
//		this.reservedWords = this.getReservedWords();
	}
	
	public String getURL(String serverName, String dbName, int port) {
		String temp = serverName.replaceAll("\\\\", "\\\\\\\\");
		String url = this.getURL().replaceAll("<SERVER NAME>", temp);
		url = url.replaceAll("<PORT>", String.valueOf(port));

		temp = dbName.replaceAll("\\\\", "\\\\\\\\");
		url = url.replaceAll("<DB NAME>", temp);

		return url;
	}
	
	@SuppressWarnings("unchecked")
	public Class<Driver> getDriverClass(String driverClassName) {
		String path = null;
		Class clazz = null;

		try {
			path = PreferenceInitializer.getJDBCDriverPath(this.getId(),driverClassName);
			ClassLoader loader = this.getClassLoader(path);
			clazz = loader.loadClass(driverClassName);

		} catch (Exception e) {
			JDBCPathDialog dialog = new JDBCPathDialog(PlatformUI
					.getWorkbench().getActiveWorkbenchWindow().getShell(), this
					.getId(), driverClassName, path,
					new ArrayList<JDBCDriverSetting>(), false);

			if (dialog.open() == IDialogConstants.OK_ID) {
				JDBCDriverSetting newDriverSetting = new JDBCDriverSetting(this
						.getId(), dialog.getDriverClassName(), dialog.getPath());

				List<JDBCDriverSetting> driverSettingList = PreferenceInitializer
						.getJDBCDriverSettingList();

				if (driverSettingList.contains(newDriverSetting)) {
					driverSettingList.remove(newDriverSetting);
				}
				driverSettingList.add(newDriverSetting);

				PreferenceInitializer
						.saveJDBCDriverSettingList(driverSettingList);

				clazz = this.getDriverClass(dialog.getDriverClassName());
			}
		}

		return clazz;
	}

	private ClassLoader getClassLoader(String uri) throws SQLException,
			MalformedURLException {

		StringTokenizer tokenizer = new StringTokenizer(uri, ";");
		int count = tokenizer.countTokens();

		URL[] urls = new URL[count];

		for (int i = 0; i < urls.length; i++) {
			urls[i] = new URL("file", "", tokenizer.nextToken());
		}

		URLClassLoader loader = new URLClassLoader(urls, this.getClass().getClassLoader());

		return loader;
	}
	
	abstract protected String getURL();
	
	abstract public String getDriverClassName();
	
	protected Set<String> getReservedWords() {
		Set<String> reservedWords = new HashSet<String>();

		ResourceBundle bundle = ResourceBundle.getBundle(this.getClass()
				.getPackage().getName()
				+ ".reserved_word");

		Enumeration<String> keys = bundle.getKeys();

		while (keys.hasMoreElements()) {
			reservedWords.add(keys.nextElement().toUpperCase());
		}

		return reservedWords;
	}

	public boolean isReservedWord(String str) {
		return reservedWords.contains(str.toUpperCase());
	}

}
